import { defineComponent } from "@/shared/tools.mjs";

export const myModalContent = html`
  <div class="modal-header">
    <h3 class="modal-title" id="modal-title">I'm a modal!</h3>
  </div>
  <div class="modal-body" id="modal-body">
    <ul>
      <li ng-repeat="item in ModalComponentCtrl.items track by $index">
        <a
          href="javascript:;"
          ng-click="ModalComponentCtrl.selected.item = item;"
          >{{ item }}</a
        >
      </li>
    </ul>
    Selected: <b>{{ ModalComponentCtrl.selected.item }}</b>
  </div>
  <div class="modal-footer">
    <button
      class="btn btn-primary"
      type="button"
      ng-click="ModalComponentCtrl.ok()"
    >
      OK
    </button>
    <button
      class="btn btn-warning"
      type="button"
      ng-click="ModalComponentCtrl.cancel()"
    >
      Cancel
    </button>
    <button ng-click="ModalComponentCtrl.handleClick()">handleClick</button>
  </div>
`;

const stackedModal = html`
  <div class="modal-header">
    <h3 class="modal-title" id="modal-title-{{name}}">The {{name}} modal!</h3>
  </div>
  <div class="modal-body" id="modal-body-{{name}}">
    Having multiple modals open at once is probably bad UX but it's technically
    possible.
  </div>
`;

/**
 * @implements {ng.IController}
 */
export class ModalInstanceCtrl {
  $onInit() {
    // this.$scope.$on("handleClick", () => {
    //   console.log("handleClick");
    // });
    console.log("ModalInstanceCtrl");
  }

  $onDestroy() {
    console.log("ModalInstanceCtrl $onDestroy");
  }

  static $inject = ["$uibModalInstance"];

  /**
   * @param {ng.ui.bootstrap.IModalInstanceService} $uibModalInstance
   * @param {string[]} items
   */
  constructor($uibModalInstance, items) {
    this.$uibModalInstance = $uibModalInstance;
    this.items = items;
    this.selected = {
      item: this.items[0],
    };
  }

  ok() {
    this.$uibModalInstance.close({ $value: this.selected.item });
  }

  cancel() {
    this.$uibModalInstance.dismiss({ $value: "cancel" });
  }
}
/**
 * 这里是外部的view的ctrl
 * @implements {ng.IController}
 */
export class ModalDemoCtrl {
  static $inject = ["$scope", "$uibModal", "$log", "$document"];

  /**
   * @param {ng.IScope} $scope
   * @param {ng.ui.bootstrap.IModalService} $uibModal
   * @param {ng.ILogService} $log
   * @param {ng.IDocumentService} $document
   */
  constructor($scope, $uibModal, $log, $document) {
    this.$scope = $scope;
    this.$uibModal = $uibModal;
    this.$log = $log;
    this.$document = $document;
    // init data
    /** @type {string[]} */
    this.items = ["item1", "item2", "item3"];
    /** @type {string | undefined} */
    this.selected = undefined;
    /** @type {boolean} */
    this.animationsEnabled = true;
  }

  /**
   * @param {string} size
   * @param {string} parentSelector
   */
  open(size, parentSelector) {
    const parentElem = parentSelector
      ? $(this.$document.find(`.modal-demo ${parentSelector}`))
      : undefined;
    const modalInstance = this.$uibModal.open({
      ...modalComponent,
      animation: this.animationsEnabled,
      ariaLabelledBy: "modal-title", // 需要等同对应的id
      ariaDescribedBy: "modal-body", // 需要等同对应的id
      size,
      appendTo: parentElem,
      // inject to constructor
      resolve: {
        items: () => this.items,
        selected: () => this.selected,
      },
      openedClass: "modal-open opened-class",
      windowClass: "window-class",
      windowTopClass: "window-top-class",
    });
    modalInstance.result.then(
      /**
       * @param {{$value: string}} selectedItem
       */
      (selectedItem) => {
        console.log("selectedItem", selectedItem);
        this.selected = selectedItem.$value;
      },
      () => {
        this.$log.info(`Modal dismissed at: ${new Date()}`);
      },
    );
  }

  openComponentModal() {
    const modalInstance = this.$uibModal.open({
      ...modalComponent,
      animation: this.animationsEnabled,
      resolve: {
        items: () => this.items,
        selected: () => this.selected,
      },
    });
    modalInstance.result.then(
      /**
       * @param {{$value: string}} selectedItem
       */
      (selectedItem) => {
        console.log("selectedItem", selectedItem);

        this.selected = selectedItem.$value;
      },
      () => {
        this.$log.info(`modal-component dismissed at: ${new Date()}`);
      },
    );
  }

  openMultipleModals() {
    this.$uibModal.open({
      animation: this.animationsEnabled,
      ariaLabelledBy: "modal-title-bottom",
      ariaDescribedBy: "modal-body-bottom",
      template: stackedModal,
      size: "sm",

      controller: class {
        /**
         * @param {ng.WIScope} $scope
         */
        constructor($scope) {
          $scope.name = "bottom";
        }
      },
    });

    this.$uibModal.open({
      animation: this.animationsEnabled,
      ariaLabelledBy: "modal-title-top",
      ariaDescribedBy: "modal-body-top",
      template: stackedModal,
      size: "sm",

      controller: class {
        /**
         * @param {ng.WIScope} $scope
         */
        constructor($scope) {
          $scope.name = "top";
        }
      },
    });
  }

  toggleAnimation() {
    this.animationsEnabled = !this.animationsEnabled;
  }

  handleClick() {
    console.log(Reflect.ownKeys(this));
  }
}
/**
 * @typedef {{$resolve: {items: string[], selected?: string | undefined}}} ModalComponentScope
 * @implements {ng.IController}
 * @return
 */

class ModalComponentCtrl {
  static $inject = ["$scope", "$uibModalInstance"];

  /**
   * @param {ng.IScope & ModalComponentScope} $scope
   * @param {ng.ui.bootstrap.IModalInstanceService} $uibModalInstance
   */
  constructor($scope, $uibModalInstance) {
    console.log($scope);
    this.$scope = $scope;
    this.$uibModalInstance = $uibModalInstance;
    this.items = $scope.$resolve.items;
    // pre init, for type
    /** @type {{item: string} | undefined} */
    this.selected = undefined;
  }

  $onInit() {
    if (this.$scope.$resolve.selected) {
      this.selected = {
        item: this.$scope.$resolve.selected,
      };
    }
  }

  ok() {
    this.$uibModalInstance.close({ $value: this.selected?.item });
  }

  cancel() {
    this.$uibModalInstance.dismiss({ $value: "cancel" });
  }

  handleClick() {
    console.log("this.$scope", this.$scope);
  }
}
/**
 * @type {{ template: string, controller: NewableFunction, controllerAs: string }}
 */
const modalComponent = defineComponent({
  controller: ModalComponentCtrl,
  controllerAs: "ModalComponentCtrl",
  template: myModalContent,
});
// / LoadEffect
__App__ &&
  __App__.component(
    "modalComponent",
    Object.assign(modalComponent, {
      bindings: {
        resolve: "<resolve",
        close: "&close",
        dismiss: "&dismiss",
      },
    }),
  );
